package <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.service.impl;

import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.constant.YesOrNo;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.core.exception.BusinessException;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.dao.CmSysMenuDao;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.dao.CmSysRoleDao;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.entity.CmSysButtonEntity;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.entity.CmSysMenuEntity;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.entity.CmSysRoleButtonEntity;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.entity.CmSysRoleEntity;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.entity.CmSysRoleMenuEntity;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.entity.PageData;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.service.CmSysRoleService;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.utils.PageUtil;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.utils.SnowflakeIdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zrx
 */
@Service
public class CmSysRoleServiceImpl implements CmSysRoleService {


	private final CmSysRoleDao roleDao;

	private final CmSysMenuDao menuDao;

	private static final String SUPER_ROLE_NAME = "超级管理员";

	@Autowired
	public CmSysRoleServiceImpl(CmSysRoleDao roleDao, CmSysMenuDao menuDao) {
		this.roleDao = roleDao;
		this.menuDao = menuDao;
	}

	@Override
	public void add(CmSysRoleEntity entity) {
		roleDao.add(entity);
	}

	@Override
	public void delete(CmSysRoleEntity entity) {
		if (entity.getRoleId() == 1) {
			throw new BusinessException("超级管理员角色不允许删除！");
		}
		roleDao.delete(entity);
	}

	@Override
	public void update(CmSysRoleEntity entity) {
		if (entity.getRoleId() == 1 && !SUPER_ROLE_NAME.equals(entity.getRoleName())) {
			throw new BusinessException("超级管理员角色不允许更改角色名称！");
		}
		//删除之前的菜单和按钮
		roleDao.delMenuByRoleId(entity.getRoleId());
		roleDao.delButtonByRoleId(entity.getRoleId());
		//获取被更新的菜单列表
		List<CmSysMenuEntity> cmSysMenuEntityList = entity.getCmSysMenuEntityList();
		cmSysMenuEntityList.forEach(menuEntity -> {
			//添加本次授权的菜单
			if (YesOrNo.YES.getCode().equals(menuEntity.getIsButton())) {
				CmSysRoleButtonEntity cmSysRoleButtonEntity = new CmSysRoleButtonEntity();
				cmSysRoleButtonEntity.setRoleButtonId(SnowflakeIdWorker.generateId());
				cmSysRoleButtonEntity.setRoleId(entity.getRoleId());
				cmSysRoleButtonEntity.setButtonId(menuEntity.getMenuId());
				cmSysRoleButtonEntity.setMenuId(menuEntity.getParentId());
				cmSysRoleButtonEntity.setCreateTime(entity.getUpdateTime());
				cmSysRoleButtonEntity.setUpdateTime(entity.getUpdateTime());
				cmSysRoleButtonEntity.setCreateUserId(entity.getUpdateUserId());
				cmSysRoleButtonEntity.setUpdateUserId(entity.getUpdateUserId());
				roleDao.addRoleButton(cmSysRoleButtonEntity);
			} else {
				CmSysRoleMenuEntity cmSysRoleMenuEntity = new CmSysRoleMenuEntity();
				cmSysRoleMenuEntity.setRoleMenuId(SnowflakeIdWorker.generateId());
				cmSysRoleMenuEntity.setMenuId(menuEntity.getMenuId());
				cmSysRoleMenuEntity.setRoleId(entity.getRoleId());
				cmSysRoleMenuEntity.setCreateTime(entity.getUpdateTime());
				cmSysRoleMenuEntity.setUpdateTime(entity.getUpdateTime());
				cmSysRoleMenuEntity.setCreateUserId(entity.getUpdateUserId());
				cmSysRoleMenuEntity.setUpdateUserId(entity.getUpdateUserId());
				roleDao.addRoleMenu(cmSysRoleMenuEntity);
			}
		});
		roleDao.update(entity);
	}

	@Override
	public PageData<CmSysRoleEntity> likeSelect(CmSysRoleEntity entity) {
		return PageUtil.getPageData(entity, roleDao);
	}

	@Override
	public List<CmSysRoleEntity> listAll() {
		return roleDao.listAll();
	}

	@Override
	public CmSysRoleEntity getById(Long roleId) {
		return roleDao.getById(roleId);
	}

	@Override
	public List<CmSysMenuEntity> getMenusById(Long roleId) {
		List<CmSysMenuEntity> resultList = new ArrayList<>(10);
		List<CmSysMenuEntity> rootMenu = menuDao.listAll(roleId, YesOrNo.NO.getCode());
		for (CmSysMenuEntity menu : rootMenu) {
			// 一级菜单parentId为0
			if (menu.getParentId() == 0) {
				resultList.add(menu);
			}
		}
		// 为一级菜单设置子菜单，getChild是递归调用的
		for (CmSysMenuEntity menu : resultList) {
			menu.setChildren(getChild(menu.getMenuId(), rootMenu));
		}
		return resultList;
	}

	@Override
	public Map<Long, List<CmSysButtonEntity>> getButtonsById(Long roleId) {
		Map<Long, List<CmSysButtonEntity>> buttons = new HashMap<>(6);
		List<CmSysMenuEntity> rootMenu = menuDao.listAll(roleId, YesOrNo.NO.getCode());
		for (CmSysMenuEntity menuEntity : rootMenu) {
			//获取每个菜单底下的按钮,前端根据当前用户的roleId判断按钮是否应该显示
			buttons.put(menuEntity.getMenuId(), menuDao.getButtonsByMenuId(menuEntity.getMenuId(), roleId, YesOrNo.YES.getCode()));
		}
		return buttons;
	}

	private List<CmSysMenuEntity> getChild(Long id, List<CmSysMenuEntity> rootMenu) {
		// 子菜单
		List<CmSysMenuEntity> childList = new ArrayList<>(10);
		for (CmSysMenuEntity menu : rootMenu) {
			// 遍历所有节点，将父菜单id与传过来的id比较
			if (menu.getParentId() != 0) {
				if (menu.getParentId().equals(id)) {
					childList.add(menu);
				}
			}
		}
		// 把子菜单的子菜单再循环一遍
		for (CmSysMenuEntity menu : childList) {
			menu.setChildren(getChild(menu.getMenuId(), rootMenu));
		}
		return childList;
	}
}
